package com.wenjie.common.enumHandler;

import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonStreamContext;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class EnumDeserializer extends JsonDeserializer<IEnum> {

    public static List<Field> findPrivateFieldsInHierarchy(Class<?> clazz, String propertyName) {
        List<Field> privateFields = new ArrayList<>();
        findPrivateFieldsInHierarchy(clazz, propertyName, privateFields);
        return privateFields;
    }

    private static void findPrivateFieldsInHierarchy(Class<?> clazz, String propertyName, List<Field> privateFields) {
        // 获取当前类的所有字段
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            if (field.getName().contains(propertyName) && java.lang.reflect.Modifier.isPrivate(field.getModifiers())) {
                privateFields.add(field);
            }
        }

        // 递归获取父类的私有字段
        Class<?> superClass = clazz.getSuperclass();
        if (superClass != null) {
            findPrivateFieldsInHierarchy(superClass, propertyName, privateFields);
        }
    }

    /**
     * 根据参数值获取对应的枚举
     *
     * @throws IOException
     * @throws JacksonException
     */
    @Override
    public IEnum deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
        // 当前值
        final String paramValue = p.getText();

        //获取序列化信息
        final JsonStreamContext parsingContext = p.getParsingContext();
        // 获取当前序列化的类的对象
        final Object currentValue = parsingContext.getCurrentValue();
        //获取当前序列化的字段名
        final String currentName = parsingContext.getCurrentName();


        Field declaredField = findPrivateFieldsInHierarchy(currentValue.getClass(), currentName).get(0);
        // 反射获取当前序列化字段信息
//            final Field declaredField = currentValue.getClass().getDeclaredField(currentName);

        // 通过字段信息获取对应的枚举的Class
        final Class<IEnum> targetType = (Class<IEnum>) declaredField.getType();

        //根据参数值获取对应的枚举
        IEnum iEnum = IEnum.getEnumByCode(targetType, paramValue);
        if (ObjectUtil.isEmpty(iEnum)) {
            throw new EnumException("[" + currentName + "]参数错误");
        }
        //返回枚举
        return iEnum;
    }


}
